package
{
	//顶点元素计算工具类
	public class VertexUtils
	{
		
		//是否使用面权重
		private static var _useFaceWeights:Boolean = true;
		//面法线
		private static var _faceNormals:Vector.<Number>;
		//面权重
		private static var _faceWeights:Vector.<Number>;
		
		private static var vertexStride:uint = 3;
		
		private static var uvStride:uint = 2;
		
		private static var offset:uint = 0;
		
		
		private static  function updateFaceNormals(vertexData:Vector.<Number>,indexData:Vector.<uint>):void
		{
			var i:uint, j:uint, k:uint;
			var index:uint;
			var len:uint = indexData.length;
			var x1:Number, x2:Number, x3:Number;
			var y1:Number, y2:Number, y3:Number;
			var z1:Number, z2:Number, z3:Number;
			var dx1:Number, dy1:Number, dz1:Number;
			var dx2:Number, dy2:Number, dz2:Number;
			var cx:Number, cy:Number, cz:Number;
			var d:Number;
			var vertices:Vector.<Number> = vertexData;
			var posStride:int = vertexStride;
			var posOffset:int = offset;
			
			_faceNormals ||= new Vector.<Number>(len, true);
			if (_useFaceWeights)
				_faceWeights ||= new Vector.<Number>(len/3, true);
			
			while (i < len) {
				index = posOffset + indexData[i++]*posStride;
				x1 = vertices[index];
				y1 = vertices[index + 1];
				z1 = vertices[index + 2];
				index = posOffset + indexData[i++]*posStride;
				x2 = vertices[index];
				y2 = vertices[index + 1];
				z2 = vertices[index + 2];
				index = posOffset + indexData[i++]*posStride;
				x3 = vertices[index];
				y3 = vertices[index + 1];
				z3 = vertices[index + 2];
				dx1 = x3 - x1;
				dy1 = y3 - y1;
				dz1 = z3 - z1;
				dx2 = x2 - x1;
				dy2 = y2 - y1;
				dz2 = z2 - z1;
				cx = dz1*dy2 - dy1*dz2;
				cy = dx1*dz2 - dz1*dx2;
				cz = dy1*dx2 - dx1*dy2;
				d = Math.sqrt(cx*cx + cy*cy + cz*cz);
				// length of cross product = 2*triangle area
				if (_useFaceWeights) {
					var w:Number = d*10000;
					if (w < 1)
						w = 1;
					_faceWeights[k++] = w;
				}
				d = 1/d;
				_faceNormals[j++] = cx*d;
				_faceNormals[j++] = cy*d;
				_faceNormals[j++] = cz*d;
			}
			
		}
		
		//求面法线
		public static  function getVertexNormals(vertexData:Vector.<Number>,indexData:Vector.<uint>,useFaceWeights:Boolean = true):Vector.<Number>
		{
			_useFaceWeights = useFaceWeights;
			updateFaceNormals(vertexData,indexData);
			
			var v1:uint;
			var f1:uint = 0, f2:uint = 1, f3:uint = 2;
			var lenV:uint = vertexData.length;
			var normalStride:int = vertexStride;
			var normalOffset:int = offset;
			
			var target:Vector.<Number> = new Vector.<Number>(lenV, true);
			v1 = normalOffset;
			while (v1 < lenV) {
				target[v1] = 0.0;
				target[v1 + 1] = 0.0;
				target[v1 + 2] = 0.0;
				v1 += normalStride;
			}
			
			var i:uint, k:uint;
			var lenI:uint = indexData.length;
			var index:uint;
			var weight:Number;
			
			while (i < lenI) {
				weight = _useFaceWeights? _faceWeights[k++] : 1;
				index = normalOffset + indexData[i++]*normalStride;
				target[index++] += _faceNormals[f1]*weight;
				target[index++] += _faceNormals[f2]*weight;
				target[index] += _faceNormals[f3]*weight;
				index = normalOffset + indexData[i++]*normalStride;
				target[index++] += _faceNormals[f1]*weight;
				target[index++] += _faceNormals[f2]*weight;
				target[index] += _faceNormals[f3]*weight;
				index = normalOffset + indexData[i++]*normalStride;
				target[index++] += _faceNormals[f1]*weight;
				target[index++] += _faceNormals[f2]*weight;
				target[index] += _faceNormals[f3]*weight;
				f1 += 3;
				f2 += 3;
				f3 += 3;
			}
			
			v1 = normalOffset;
			while (v1 < lenV) {
				var vx:Number = target[v1];
				var vy:Number = target[v1 + 1];
				var vz:Number = target[v1 + 2];
				var d:Number = 1.0/Math.sqrt(vx*vx + vy*vy + vz*vz);
				target[v1] = vx*d;
				target[v1 + 1] = vy*d;
				target[v1 + 2] = vz*d;
				v1 += normalStride;
			}
			return target;
		}
		//求顶点法线还没写
		
	}
}